// lib/src/services/auth_service.dart

import 'dart:convert';
import 'dart:io';

import '../models/customer.dart';
import 'storage_service.dart';
import 'logging_service.dart'; // 新增：导入日志服务

/// 用户角色枚举
enum UserRole { trader, customer, none }

/// 认证服务，负责用户登录、登出及状态管理 (状态持久化到文件)。
class AuthService {
  final StorageService _storageService;
  final LoggingService _loggingService; // 新增：日志服务实例
  static const String _sessionFileName = 'data/session.json';

  UserRole _currentRole = UserRole.none;
  Customer? _currentCustomer;
  String? _currentTraderUsername;
  bool _isInitialized = false;

  /// 私有构造函数
  AuthService._(this._storageService, this._loggingService); // 修改：接收日志服务

  /// 静态工厂方法，创建并异步初始化 AuthService 实例。
  static Future<AuthService> create(
    StorageService storageService,
    LoggingService loggingService,
  ) async {
    // 修改：接收日志服务
    final service = AuthService._(storageService, loggingService);
    await service.init();
    return service;
  }

  Future<void> init() async {
    if (_isInitialized) return;
    await _loadSession();
    _isInitialized = true;
    // _loggingService.info("AuthService initialized, session state loaded."); // 日志记录初始化
    print("AuthService initialized, session state loaded.");
  }

  Future<void> _loadSession() async {
    try {
      final file = File(_sessionFileName);
      if (await file.exists()) {
        final content = await file.readAsString(encoding: utf8);
        if (content.isNotEmpty) {
          final Map<String, dynamic> sessionData = jsonDecode(content);
          final roleString = sessionData['role'] as String?;
          final identifier = sessionData['identifier'] as String?;

          if (roleString != null && identifier != null) {
            if (roleString == 'trader') {
              _currentRole = UserRole.trader;
              _currentTraderUsername = identifier;
              _loggingService.info('Trader "$identifier" session restored.');
            } else if (roleString == 'customer') {
              final customer = _storageService.getCustomerByCode(identifier);
              if (customer != null) {
                _currentRole = UserRole.customer;
                _currentCustomer = customer;
                _loggingService.info(
                  'Customer "${customer.customerName}" (Code: $identifier) session restored.',
                );
              } else {
                _loggingService.warning(
                  'Customer code "$identifier" from session file is invalid. Clearing session.',
                );
                await _clearSession();
              }
            } else {
              _currentRole = UserRole.none;
            }
          } else {
            _currentRole = UserRole.none;
          }
        } else {
          _currentRole = UserRole.none;
        }
      } else {
        _currentRole = UserRole.none;
        _loggingService.info(
          'Session file not found. Starting with no active session.',
        );
      }
    } catch (e, s) {
      _loggingService.error(
        'Error loading session file.',
        error: e,
        stackTrace: s,
      );
      _currentRole = UserRole.none;
      await _clearSession();
    }
  }

  Future<void> _saveSession() async {
    Map<String, dynamic> sessionData = {};
    if (_currentRole == UserRole.trader && _currentTraderUsername != null) {
      sessionData = {'role': 'trader', 'identifier': _currentTraderUsername};
    } else if (_currentRole == UserRole.customer && _currentCustomer != null) {
      sessionData = {
        'role': 'customer',
        'identifier': _currentCustomer!.customerCode,
      };
    }

    try {
      final file = File(_sessionFileName);
      if (!await file.parent.exists()) {
        await file.parent.create(recursive: true);
      }
      await file.writeAsString(
        jsonEncode(sessionData),
        encoding: utf8,
        flush: true,
      );
    } catch (e, s) {
      _loggingService.error(
        'Error saving session file.',
        error: e,
        stackTrace: s,
      );
    }
  }

  Future<void> _clearSession() async {
    _currentRole = UserRole.none;
    _currentCustomer = null;
    _currentTraderUsername = null;
    await _saveSession();
    // _loggingService.info('Session cleared.'); // logout 会记录更完整的日志
  }

  UserRole get currentRole => _currentRole;
  Customer? get currentCustomer =>
      _currentRole == UserRole.customer ? _currentCustomer : null;
  String? get currentTraderUsername =>
      _currentRole == UserRole.trader ? _currentTraderUsername : null;

  bool isLoggedIn() {
    return _currentRole != UserRole.none;
  }

  String getCurrentLanguageCode() {
    if (_currentRole == UserRole.customer && _currentCustomer != null) {
      return _currentCustomer!.languageCode;
    }
    return 'en';
  }

  Future<bool> login(
    UserRole role,
    String identifier, {
    String? password,
  }) async {
    await logout();

    bool loginSuccess = false;
    // String roleName = role.toString().split('.').last; // 移除了未使用的变量 roleName

    if (role == UserRole.trader) {
      const validTraderUsernames = ['trader1', 'admin'];
      if (validTraderUsernames.contains(identifier)) {
        _currentRole = UserRole.trader;
        _currentTraderUsername = identifier;
        loginSuccess = true;
        _loggingService.info('Trader "$identifier" logged in successfully.');
        print('Trader "$identifier" logged in successfully.');
      } else {
        _loggingService.warning(
          'Trader login failed for username "$identifier": Invalid credentials.',
        );
        print('Trader login failed: Invalid username or password.');
      }
    } else if (role == UserRole.customer) {
      final customer = _storageService.getCustomerByCode(identifier);
      if (customer != null) {
        _currentRole = UserRole.customer;
        _currentCustomer = customer;
        loginSuccess = true;
        _loggingService.info(
          'Customer "${customer.customerName}" (Code: $identifier) logged in successfully.',
        );
        print(
          'Customer "${customer.customerName}" (Code: ${customer.customerCode}) logged in successfully.',
        );
      } else {
        _loggingService.warning(
          'Customer login failed for code "$identifier": Customer not found.',
        );
        print('Customer login failed: Customer code "$identifier" not found.');
      }
    } else {
      _loggingService.error('Login attempt with unknown role.');
      print('Login failed: Unknown user role.');
    }

    if (loginSuccess) {
      await _saveSession();
    } else {
      _currentRole = UserRole.none;
      _currentCustomer = null;
      _currentTraderUsername = null;
    }
    return loginSuccess;
  }

  Future<void> logout() async {
    if (isLoggedIn()) {
      String userDesc =
          _currentRole == UserRole.trader
              ? "Trader $_currentTraderUsername"
              : "Customer ${_currentCustomer?.customerCode}";
      _loggingService.info('$userDesc logged out.');
      print('$userDesc logged out.');
    }
    await _clearSession();
    // _loggingService.info('Session cleared and saved after logout.'); // _clearSession 内部会保存
    print('Session cleared and saved.');
  }
}
